using System;
using System.Collections.Generic;
using System.Linq;
using microsoft_TODO.DTOs;
using microsoft_TODO.MongoCore;
using microsoft_TODO.ServiceCore;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using server.DTOs;
using server.Helpers;

namespace microsoft_TODO.Controllers
{

  [Route("api/[controller]")]
  [ApiController]
  public class TaskController : ControllerBase
  {

    ILogger<TaskController> _logger;
    ITaskService _taskService;

    public TaskController(
        ILogger<TaskController> logger,
        ITaskService taskService)
    {
      _logger = logger;
      _taskService = taskService;
    }

    /// <summary>
    /// 添加新的待办事项
    /// </summary>
    /// <param name="dto">清单ID(ListId) / 事项名称(Todo)</param>
    /// <returns></returns>
    [HttpPost]
    [ProducesResponseType(201)]
    [ProducesResponseType(400)]
    public ActionResult<Models.Task> Post(NewTaskDto dto)
    {
      try
      {
        var newTask = _taskService.AddNewTask(dto);
        _logger.LogInformation(LoggingEvents.InsertItem, "Add Task {@dto}", dto);
        return Created("", newTask);
      }
      catch (Exception ex)
      {
        _logger.LogError(ex, "Failed to Add Task {@dto}", dto);
        return BadRequest();
      }
    }

    /// <summary>
    /// 添加我的一天待办事项
    /// </summary>
    /// <param name="dto">清单ID(ListId) / 事项名称(Todo)</param>
    /// <returns></returns>
    [HttpPost("myday")]
    [ProducesResponseType(201)]
    [ProducesResponseType(400)]
    public ActionResult<Models.Task> PostMyday(NewTaskDto dto)
    {
      try
      {
        var newTask = _taskService.AddTodayTask(dto);
        _logger.LogInformation(LoggingEvents.InsertItem, "Add task into My-day {@dto}", dto);
        return Created("", newTask);
      }
      catch (Exception ex)
      {
        _logger.LogError(ex, "Failed to Add task into My-day {@dto}", dto);
        return BadRequest();
      }
    }

    /// <summary>
    /// 更新待办事项
    /// </summary>
    /// <param name="dto"></param>
    /// <remarks>
    /// 以下参数为必填，其他参数每次请求只能更新一个（只需填一个需要更新的参数即可）
    ///
    ///     listId: 所属清单ID(list.id)
    ///     index: 该待办事项在清单数组的下标(task.index)
    ///
    /// </remarks>
    /// <returns></returns>
    [HttpPut]
    [ProducesResponseType(200)]
    [ProducesResponseType(400)]
    public ActionResult Put(PutTaskDto dto)
    {
      try
      {
        _logger.LogInformation(LoggingEvents.UpdateItem, "Update Task {@dto}", dto);
        _taskService.UpdateTask(dto);
        return Ok();
      }
      catch (Exception ex)
      {
        _logger.LogError(ex, "Failed to Update Task {@dto}", dto);
        return BadRequest();
      }
    }

    /// <summary>
    /// 删除待办事项
    /// </summary>
    /// <param name="lid">所属清单ID</param>
    /// <param name="index">该待办事项在清单数组的下标</param>
    /// <remarks>
    /// codes:
    ///
    ///     4005: "未找到要删除的元素"
    ///
    /// </remarks>
    /// <returns></returns>
    [HttpDelete("{lid}/{index}")]
    [ProducesResponseType(200)]
    [ProducesResponseType(404)]
    [ProducesResponseType(400)]
    public IActionResult Delete(string lid, int index)
    {
      try
      {
        _logger.LogInformation(LoggingEvents.DeleteItem, "Delete Task({index}) from {listId}", index, lid);
        if (_taskService.RemoveTask(lid, index))
          return Ok();
        return NotFound(new { code = LoggingEvents.DeleteItemNotFound });
      }
      catch (Exception ex)
      {
        _logger.LogError(ex, "Failed to Delete Task({index}) from {listId}", index, lid);
        return BadRequest();
      }
    }

    /// <summary>
    /// 移动待办事项（即添加到新的清单中）
    /// </summary>
    /// <param name="dto"></param>
    /// <returns></returns>
    [HttpPost("move")]
    [ProducesResponseType(200)]
    [ProducesResponseType(400)]
    public IActionResult MoveTask([FromBody] MoveTaskDto dto)
    {
      try
      {
        _taskService.MoveToAnotherList(dto);
        return Ok();
      }
      catch (Exception)
      {
        return BadRequest();
      }
    }

    /// <summary>
    /// 清除截止日期
    /// </summary>
    /// <param name="lid">ListId</param>
    /// <param name="index">该待办事项在清单数组的下标</param>
    /// <returns></returns>
    [HttpDelete("{lid}/{index}/deadline")]
    [ProducesResponseType(200)]
    [ProducesResponseType(404)]
    [ProducesResponseType(400)]
    public IActionResult ClearDeadline(string lid, int index)
    {
      try
      {
        _logger.LogInformation(LoggingEvents.UpdateItem, "Clear Task({index})'s deadline from listId({listId})", index, lid);
        if (_taskService.ClearTaskDeadline(lid, index))
          return Ok();
        return NotFound(new { code = LoggingEvents.UpdateItemNotFound });
      }
      catch (Exception ex)
      {
        _logger.LogError(ex, "Failed to Clear Task({index})'s deadline from listId({listId})", index, lid);
        return BadRequest();
      }
    }
  }
}